// , Node, Cell, Dom, Edge, Shape
import { Graph, Dom } from "@antv/x6";
import dagre from "dagre";
import insertCss from "insert-css";
import { getJsonData } from "@/api";

insertCss(`
    @keyframes ant-line {
      to {
          stroke-dashoffset: -1000
      }
    }
`);

export default function initPage(domNode, itemClickFun) {
  // 方向映射
  const dirMap = {
    LR: "LR",
    RL: "RL",
    TB: "TB",
    BT: "BT",
  };

  const colorMap = {
    normal: "#F3F8FF", // 默认正常
    selected: "#CAEAFF", // 选中正常
    abnormal: "#FFF3F3", // 默认异常
    selectedAbnormal: "#FFD8D8", // 选中异常
  };

  // 自定义节点
  Graph.registerNode(
    "org-node",
    {
      width: 70,
      height: 70,
      markup: [
        {
          tagName: "rect",
          attrs: {
            class: "card",
          },
        },
        {
          tagName: "image",
          attrs: {
            class: "image",
          },
        },
        {
          tagName: "text",
          selector: 'text',
          attrs: {
            class: "name",
            // fill: '#000000',
            // style: "background-color: #000; !important", // 添加背景色
          },
        },
        { 
          tagName: "g",
          attrs: {
            class: "btn-group",
          },
          children: [
            {
              tagName: "rect",
              attrs: {
                class: "btn",
              },
            },
            {
              tagName: "path",
              attrs: {
                class: "btn-sign",
              },
            },
          ],
        },
      ],
      attrs: {
        ".card": {
          rx: 13,
          ry: 13,
          refWidth: "100%",
          refHeight: "100%",
          fill: "#ffffff",
          // stroke: '#5F95FF',
          strokeWidth: 1,
          event: "node:card",
          cursor: "pointer",
        },
        ".image": {
          x: 16,
          y: 16,
          width: 40,
          height: 40,
          opacity: 1,
          event: "node:image",
          cursor: "pointer",
        },
        ".name": {
          refX: 35,
          refY: 80,
          fill: "#2D3E53",
          fontFamily: "PingFang SC-Regular",
          fontSize: 12,
          textAnchor: "middle",
        },
        ".btn-group": {
          // 移除固定的 refX 和 refY
          // 位置将在运行时动态设置
        },
        ".btn": {
          fill: "#47CEA2",
          stroke: "#fff",
          x: -10,
          y: -10,
          height: 20,
          width: 20,
          rx: 10,
          ry: 10,
          cursor: "pointer",
          event: "node:collapse",
        },
        ".btn-sign": {
          refX: -5,
          refY: -5,
          stroke: "#FFFFFF",
          strokeWidth: 1.6,
          d: "M 2 5 8 5",
        },
      },
    },
    true
  );

  // 自定义边
  Graph.registerEdge(
    "org-edge",
    {
      zIndex: -1,
      attrs: {
        line: {
          strokeWidth: 2,
          stroke: "#A2B1C3",
          sourceMarker: null,
          targetMarker: null,
        },
      },
    },
    true
  );

  const icon = "https://img2.baidu.com/it/u=100435909,14055296&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=625";
  // 布局方向
  const dir = dirMap.TB;

  // 创建画布
  const graph = new Graph({
    width: "100%",
    height: 900,
    container: domNode,
    scroller: true,
    interacting: false,
    background: {
      color: "#fff", // 设置画布背景颜色
    },
    grid: {
      size: 10, // 网格大小 10px
      visible: true, // 渲染网格背景
    },
  });

  // 监听自定义事件
  function setup() {
    graph.on("node:card", ({ e, node }) => {
      e.stopPropagation();
      if (typeof itemClickFun === "function") {
        itemClickFun({ e, node });
      }
    });

    graph.on("node:image", ({ e, node }) => {
      e.stopPropagation();
      if (typeof itemClickFun === "function") {
        itemClickFun({ e, node });
      }
    });

    // Add hover handlers
    graph.on("node:mouseenter", ({ node }) => {
      node.attr(".card", {
        stroke: "#5F95FF",
        strokeWidth: 1,
      });
    });

    graph.on("node:mouseleave", ({ node }) => {
      node.attr(".card", {
        stroke: "none",
        strokeWidth: 1,
      });
    });

    // Add collapse handler
    graph.on("node:collapse", ({ node }) => {
      console.log("node:collapse", node);
      const collapsed = typeof node.getData()?.collapsed === "undefined" ? true : node.getData()?.collapsed;
      console.log("node:collapsed", collapsed);

      node.setData({ collapsed: !collapsed });

      // Update button sign
      node.attr(".btn-sign", {
        d: !collapsed ? "M 2 5 8 5" : "M 1 5 9 5 M 5 1 5 9",
        strokeWidth: !collapsed ? 1.8 : 1.8,
      });

      // Toggle visibility of successor nodes
      const successors = graph.getSuccessors(node);
      if (successors) {
        successors.forEach((successor) => {
          successor.setVisible(!collapsed);
          const edges = graph.getConnectedEdges(successor);
          edges.forEach((edge) => edge.setVisible(!collapsed));
        });
      }

      computedPosition();
    });
  }

  // 计算位置
  function computedPosition() {
    const nodes = graph.getNodes();
    const edges = graph.getEdges();
    const g = new dagre.graphlib.Graph();
    g.setGraph({ rankdir: dir, nodesep: 50, ranksep: 50 });
    g.setDefaultEdgeLabel(() => ({}));

    const width = 70;
    const height = 70;
    nodes.forEach((node) => {
      g.setNode(node.id, { width, height });
    });

    edges.forEach((edge) => {
      const source = edge.getSource();
      const target = edge.getTarget();
      g.setEdge(source.cell, target.cell);
    });

    dagre.layout(g);

    g.nodes().forEach((id) => {
      const node = graph.getCellById(id);
      if (node) {
        const pos = g.node(id);
        node.position(pos.x, pos.y);
      }
    });

    edges.forEach((edge) => {
      const source = edge.getSourceNode();
      const target = edge.getTargetNode();

      const sourceBBox = source.getBBox();
      const targetBBox = target.getBBox();

      if ((dir === "LR" || dir === "RL") && sourceBBox.y !== targetBBox.y) {
        const gap = dir === "LR" ? targetBBox.x - sourceBBox.x - sourceBBox.width : -sourceBBox.x + targetBBox.x + targetBBox.width;
        const fix = dir === "LR" ? sourceBBox.width : 0;
        const x = sourceBBox.x + fix + gap / 2;
        edge.setVertices([
          { x, y: sourceBBox.center.y },
          { x, y: targetBBox.center.y },
        ]);
      } else if ((dir === "TB" || dir === "BT") && sourceBBox.x !== targetBBox.x) {
        const gap = dir === "TB" ? targetBBox.y - sourceBBox.y - sourceBBox.height : -sourceBBox.y + targetBBox.y + targetBBox.height;
        const fix = dir === "TB" ? sourceBBox.height : 0;
        const y = sourceBBox.y + fix + gap / 2;
        edge.setVertices([
          { x: sourceBBox.center.x, y },
          { x: targetBBox.center.x, y },
        ]);
      } else {
        edge.setVertices([]);
      }
    });
  }

  function createNode(item, image) {

    let btnGroup = {};
    if (item.children && item.children.length > 0) {
      btnGroup = (() => {
        switch (dir) {
          case "TB":
            return { refX: "50%", refY: "100%", x: 15, y: -5 };
          case "BT":
            return { refX: "50%", refY: 0, x: -15, y: -15 };
          case "LR":
            return { refX: "100%", refY: "50%", x: -5, y: -10 };
          case "RL":
            return { refX: 0, refY: "50%", x: -25, y: -10 };
          default:
            return { refX: "100%", refY: "50%", x: -10, y: -10 };
        }
      })();
    } else {
      btnGroup.display = "none";
    }

    // 是否可折叠
    if(item.collapsible){
      btnGroup.display = "block";
    }else{
      btnGroup.display = "none";
    }

    return graph.createNode({
      id: item.id,
      data: item,
      shape: "org-node",
      attrs: {
        ".card": {
          fill: colorMap.normal,
        },
        ".image": { xlinkHref: image },
        ".name": {
          text: Dom.breakText(item.name, { width: 70, height: 45 }),
        },
        // 默认隐藏按钮组
        ".btn-group": btnGroup,
      },
    });
  }

  function createEdge(source, target, item) {
    return graph.createEdge({
      shape: "org-edge",
      source: { cell: source.id },
      target: { cell: target.id },
      // label: source.id,
      attrs: {
        line:
          item.connectionType == "solid"
            ? {
                stroke: "#1890ff",
                strokeDasharray: 5,
                style: {
                  animation: "ant-line 30s infinite linear",
                },
              }
            : {},
      },
    });
  }

  // 树转数组
  function treeToArray(tree) {
    const arr = [];
    tree.forEach((item) => {
      arr.push(item);
      if (item.children) {
        arr.push(...treeToArray(item.children));
      }
    });
    return arr;
  }

  const nodes = [];
  const edges = [];

  const { data } = getJsonData();
  const list = treeToArray(data);

  for (const item of list) {
    const node = createNode(item, icon);
    nodes.push(node);
    if (item.children && item.children.length > 0) {
      for (const child of item.children) {
        const edge = createEdge(node, createNode(child, icon), child);
        edges.push(edge);
      }
    }
  }

  graph.resetCells([...nodes, ...edges]);

  computedPosition();
  setup();
}
